namespace PlexMediaLinker
{
    public partial class MainForm : Form
    {
        private NotifyIcon tray;
        private ContextMenuStrip trayMenu;
        private readonly List<FileSystemWatcher> watchers = [];
        private TextBox logTextBox;
        private CheckBox chkAutoScroll;
        private DataGridView dataGridView;
        private System.Windows.Forms.Timer autoSyncTimer;
        private CheckBox chkAutoSync;
        private NumericUpDown numSyncInterval;

        public MainForm()
        {
            InitializeComponent();
            InitTray();
            InitDataGrid();
            InitLogger();
            InitAutoSyncTimer();
            StartAllWatchers();
        }

        private void InitializeComponent()
        {
            Text = "Plex Media Linker";
            FormClosing += MainForm_FormClosing;
            Resize += MainForm_Resize;
            ClientSize = new Size(800, 600);

            // 创建主容器
            var mainContainer = new SplitContainer
            {
                Dock = DockStyle.Fill,
                Orientation = Orientation.Horizontal,
                SplitterDistance = 350
            };

            // 上半部分：DataGridView 和按钮
            var topPanel = new Panel { Dock = DockStyle.Fill };
            dataGridView = new DataGridView { Dock = DockStyle.Fill, DataSource = Config.Groups, AutoGenerateColumns = true };

            // 顶部按钮和全局自启复选框
            var buttonPanel = new FlowLayoutPanel { Dock = DockStyle.Top, Height = 40 };
            var btnAdd = new Button { Text = "添加组" };
            var btnRemove = new Button { Text = "删除选中组" };
            var btnScan = new Button { Text = "全量同步" };
            var chkAuto = new CheckBox { Text = "开机自启动", Checked = Config.GlobalAutoStart, AutoSize = true };

            // 添加定时同步控件
            chkAutoSync = new CheckBox { Text = "定时全量同步", Checked = Config.AutoSyncEnabled, AutoSize = true };
            numSyncInterval = new NumericUpDown
            {
                Minimum = 1,
                Maximum = 1440,
                Value = Config.AutoSyncIntervalMinutes,
                Width = 60,
                DecimalPlaces = 0
            };
            var lblMinutes = new Label { Text = "分钟", AutoSize = true };

            btnAdd.Click += (s, e) => AddGroup();
            btnRemove.Click += (s, e) => RemoveSelectedGroup();
            btnScan.Click += (s, e) => FullScanSelected();
            chkAuto.CheckedChanged += (s, e) => { Config.GlobalAutoStart = chkAuto.Checked; Config.Save(); };
            chkAutoSync.CheckedChanged += (s, e) =>
            {
                Config.AutoSyncEnabled = chkAutoSync.Checked;
                Config.Save();
                UpdateAutoSyncTimer();
            };
            numSyncInterval.ValueChanged += (s, e) =>
            {
                Config.AutoSyncIntervalMinutes = (int)numSyncInterval.Value;
                Config.Save();
                UpdateAutoSyncTimer();
            };

            buttonPanel.Controls.AddRange([btnAdd, btnRemove, btnScan, chkAuto, chkAutoSync, numSyncInterval, lblMinutes]);

            topPanel.Controls.Add(dataGridView);
            topPanel.Controls.Add(buttonPanel);
            mainContainer.Panel1.Controls.Add(topPanel);

            // 下半部分：日志输出框
            var logPanel = new Panel { Dock = DockStyle.Fill };
            var logHeaderPanel = new FlowLayoutPanel { Dock = DockStyle.Top, Height = 30 };
            var lblLog = new Label { Text = "调试信息:", AutoSize = true, Margin = new Padding(3, 6, 3, 3) };
            chkAutoScroll = new CheckBox { Text = "自动滚动", Checked = true, AutoSize = true, Margin = new Padding(3, 6, 3, 3) };
            var btnClear = new Button { Text = "清空", Size = new Size(60, 23), Margin = new Padding(3, 3, 3, 3) };
            btnClear.Click += (s, e) => logTextBox.Clear();
            logHeaderPanel.Controls.AddRange([lblLog, chkAutoScroll, btnClear]);

            logTextBox = new TextBox
            {
                Dock = DockStyle.Fill,
                Multiline = true,
                ScrollBars = ScrollBars.Vertical,
                ReadOnly = true,
                BackColor = Color.Black,
                ForeColor = Color.LightGreen,
                Font = new Font("Consolas", 9)
            };

            logPanel.Controls.Add(logTextBox);
            logPanel.Controls.Add(logHeaderPanel);
            mainContainer.Panel2.Controls.Add(logPanel);

            Controls.Add(mainContainer);
        }

        private void InitLogger()
        {
            Logger.LogReceived += OnLogReceived;
            Logger.WriteInfo("程序启动完成");
        }

        private void OnLogReceived(string message)
        {
            if (logTextBox.InvokeRequired)
            {
                logTextBox.Invoke(new Action<string>(OnLogReceived), message);
                return;
            }

            logTextBox.AppendText(message + Environment.NewLine);

            if (chkAutoScroll.Checked)
            {
                logTextBox.SelectionStart = logTextBox.Text.Length;
                logTextBox.ScrollToCaret();
            }
        }

        private void InitDataGrid()
        {
            // 现在不需要这个方法了，因为在 InitializeComponent 中已经设置了数据源
        }

        private void AddGroup()
        {
            var dialog = new GroupDialog();
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var cfg = dialog.Config;
                if (string.IsNullOrWhiteSpace(cfg.Name)) cfg.Name = $"第{Config.Groups.Count + 1}组";
                Config.Groups.Add(cfg);
                StartWatcher(cfg);
                Config.Save();
                Logger.WriteInfo($"[{cfg.Name}] 添加新组完成");
            }
        }

        private void RemoveSelectedGroup()
        {
            if (dataGridView.CurrentRow?.DataBoundItem is GroupConfig cfg)
            {
                StopWatcher(cfg);
                Config.Groups.Remove(cfg);
                Config.Save();
                Logger.WriteInfo($"[{cfg.Name}] 删除组完成");
            }
            else
            {
                Logger.WriteError("请先选择要删除的组");
            }
        }

        private void FullScanSelected()
        {
            if (dataGridView.CurrentRow?.DataBoundItem is GroupConfig cfg)
            {
                Logger.WriteInfo($"[{cfg.Name}] 开始全量同步");
                Scanner.ScanAndLink(cfg);
                if (cfg.RemoveMissing) Scanner.RemoveDeadLinks(cfg);
                Logger.WriteInfo($"[{cfg.Name}] 全量同步完成");
            }
            else
            {
                Logger.WriteError("请先选择要同步的组");
            }
        }

        private void InitTray()
        {
            tray = new NotifyIcon { Icon = SystemIcons.Application, Text = "Plex Media Linker", Visible = true };
            trayMenu = new ContextMenuStrip();
            // 恢复主界面
            trayMenu.Items.Add("显示主界面", null, (s, e) => ShowWindow());
            // 全部同步
            trayMenu.Items.Add("全部同步", null, (s, e) =>
            {
                Logger.WriteInfo("开始全部同步");
                foreach (var g in Config.Groups)
                {
                    Logger.WriteInfo($"[{g.Name}] 开始同步");
                    Scanner.ScanAndLink(g);
                    if (g.RemoveMissing) Scanner.RemoveDeadLinks(g);
                    Logger.WriteInfo($"[{g.Name}] 同步完成");
                }
                Logger.WriteInfo("全部同步完成");
            });
            // 开机自启切换
            var autoItem = new ToolStripMenuItem("开机自启动")
            {
                Checked = AutoStartManager.IsEnabled(),
                CheckOnClick = true
            };
            autoItem.CheckedChanged += (s, e) =>
            {
                Config.GlobalAutoStart = autoItem.Checked;
                Config.Save();
                Logger.WriteInfo($"开机自启动已{(autoItem.Checked ? "启用" : "禁用")}");
            };
            trayMenu.Items.Add(autoItem);
            // 退出
            trayMenu.Items.Add("退出", null, (s, e) => Application.Exit());

            tray.ContextMenuStrip = trayMenu;
            tray.DoubleClick += (s, e) => ShowWindow();
        }

        private void ShowWindow()
        {
            Show();
            WindowState = FormWindowState.Normal;
            BringToFront();
        }


        private void MainForm_Resize(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                Hide();
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                WindowState = FormWindowState.Minimized;
                Hide();
            }
            else
            {
                autoSyncTimer?.Stop();
                autoSyncTimer?.Dispose();
                tray.Visible = false;
            }
        }

        private void StartAllWatchers()
        {
            foreach (var cfg in Config.Groups) StartWatcher(cfg);
        }

        private void StartWatcher(GroupConfig cfg)
        {
            try
            {
                if (!Directory.Exists(cfg.Source))
                {
                    Logger.WriteError($"[{cfg.Name}] 源目录不存在: {cfg.Source}");
                    return;
                }

                var fsw = new FileSystemWatcher(cfg.Source)
                {
                    IncludeSubdirectories = true,
                    EnableRaisingEvents = true,
                    NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite
                };
                fsw.Created += (s, e) => OnCreated(e.FullPath, cfg);
                fsw.Changed += (s, e) => OnCreated(e.FullPath, cfg);
                fsw.Deleted += (s, e) => OnDeleted(e.FullPath, cfg);
                fsw.Renamed += (s, e) => { OnDeleted(e.OldFullPath, cfg); OnCreated(e.FullPath, cfg); };
                watchers.Add(fsw);

                Logger.WriteInfo($"[{cfg.Name}] 启动监视器: {cfg.Source}");
                Scanner.ScanAndLink(cfg);
                if (cfg.RemoveMissing) Scanner.RemoveDeadLinks(cfg);
            }
            catch (Exception ex)
            {
                Logger.WriteError($"[{cfg.Name}] 启动监视器失败: {ex.Message}");
            }
        }

        private void StopWatcher(GroupConfig cfg)
        {
            var w = watchers.FirstOrDefault(x => x.Path == cfg.Source);
            if (w != null)
            {
                w.EnableRaisingEvents = false;
                watchers.Remove(w);
                w.Dispose();
                Logger.WriteInfo($"[{cfg.Name}] 停止监视器");
            }
        }

        private void OnCreated(string path, GroupConfig cfg)
        {
            if (Directory.Exists(path))
            {
                // 异步处理，避免阻塞主线程
                Task.Run(() =>
                {
                    var files = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
                                         .Where(f => Scanner.ShouldProcessFile(f, cfg))
                                         .ToList();

                    int success = 0, fail = 0;
                    foreach (var file in files)
                    {
                        if (WaitForFileReady(file, 10, 500))
                        {
                            try
                            {
                                Scanner.ProcessFile(file, cfg);
                                success++;
                            }
                            catch (Exception ex)
                            {
                                Logger.WriteError($"[{cfg.Name}] 处理文件失败: {file}，原因: {ex.Message}");
                                fail++;
                            }
                        }
                        else
                        {
                            Logger.WriteError($"[{cfg.Name}] 文件长时间占用或写入未完成，跳过: {file}");
                            fail++;
                        }
                    }
                    Logger.WriteInfo($"[{cfg.Name}] 处理新目录: {Path.GetFileName(path)}，共 {files.Count} 个文件，成功 {success}，失败 {fail}");
                });
                return;
            }

            // 单文件创建，等待文件可独占打开
            Task.Run(() =>
            {
                if (Scanner.ShouldProcessFile(path, cfg))
                {
                    if (WaitForFileReady(path, 10, 500))
                    {
                        try
                        {
                            Scanner.ProcessFile(path, cfg);
                        }
                        catch (Exception ex)
                        {
                            Logger.WriteError($"[{cfg.Name}] 处理文件失败: {path}，原因: {ex.Message}");
                        }
                    }
                    else
                    {
                        Logger.WriteError($"[{cfg.Name}] 文件长时间占用或写入未完成，跳过: {path}");
                    }
                }
            });
        }

        /// <summary>
        /// 等待文件可独占打开（即写入完成），最多重试 retry 次，每次间隔 intervalMs 毫秒
        /// </summary>
        private bool WaitForFileReady(string file, int retry = 10, int intervalMs = 500)
        {
            for (int i = 0; i < retry; i++)
            {
                try
                {
                    using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.None))
                    {
                        return true;
                    }
                }
                catch
                {
                    Thread.Sleep(intervalMs);
                }
            }
            return false;
        }

        private void OnDeleted(string path, GroupConfig cfg)
        {
            // if (Scanner.ShouldProcessFile(path, cfg) && File.Exists(path))
            // {
            //     // 处理单个文件删除
            //     Scanner.DeleteFile(path, cfg);
            // }
            // else if (Directory.Exists(path) || !File.Exists(path))
            // {
            //     // 处理文件夹删除逻辑保持不变
            //     var relativePath = Path.GetRelativePath(cfg.Source, path);
            //     string targetPath;

            //     if (cfg.Structure == StructureMode.Flatten)
            //     {
            //         // 扁平化模式下不做目录级文件名猜测删除，交由 RemoveDeadLinks 统一处理
            //         Logger.WriteInfo($"[{cfg.Name}] 扁平化模式下目录删除事件，跳过文件名猜测删除，等待全量清理。");
            //     }
            //     else
            //     {
            //         // 保持结构模式：删除对应的目标文件夹
            //         targetPath = Path.Combine(cfg.Target, relativePath);
            //         if (Directory.Exists(targetPath))
            //         {
            //             try
            //             {
            //                 Directory.Delete(targetPath, true);
            //                 Logger.WriteDelete($"[{cfg.Name}] 删除目录: {targetPath}");
            //             }
            //             catch (Exception ex)
            //             {
            //                 Logger.WriteError($"[{cfg.Name}] 删除目录失败: {ex.Message}");
            //                 // 删除失败，尝试逐个删除文件并清理空目录
            //                 try
            //                 {
            //                     foreach (var f in Directory.EnumerateFiles(targetPath, "*.*", SearchOption.AllDirectories))
            //                     {
            //                         if (Scanner.ShouldProcessFile(f, cfg))
            //                         {
            //                             try
            //                             {
            //                                 var fi = new FileInfo(f);
            //                                 if (fi.IsReadOnly) fi.IsReadOnly = false;
            //                                 File.Delete(f);
            //                                 Logger.WriteDelete($"[{cfg.Name}] 删除文件: {f}");
            //                             }
            //                             catch (Exception fileEx)
            //                             {
            //                                 Logger.WriteError($"[{cfg.Name}] 删除文件失败: {fileEx.Message}");
            //                             }
            //                         }
            //                     }
            //                     // 尝试删除空目录，保护根目录
            //                     CleanEmptyDirectories(targetPath, cfg, isRoot: false, rootLimit: cfg.Target);
            //                 }
            //                 catch (Exception enumEx)
            //                 {
            //                     Logger.WriteError($"[{cfg.Name}] 枚举目标目录文件失败: {enumEx.Message}");
            //                 }
            //             }
            //         }
            //     }
            // }

            if (cfg.RemoveMissing)
                Scanner.RemoveDeadLinks(cfg);
        }

        // 递归删除空目录的辅助方法
        private void CleanEmptyDirectories(string path, GroupConfig cfg)
        {
            try
            {
                if (!Directory.Exists(path)) return;

                // 先清理所有子目录
                foreach (var subDir in Directory.GetDirectories(path))
                {
                    CleanEmptyDirectories(subDir, cfg);
                }

                // 如果当前目录为空，删除它
                if (!Directory.EnumerateFileSystemEntries(path).Any())
                {
                    Directory.Delete(path);
                    Logger.WriteClean($"[{cfg.Name}] 删除空目录: {path}");

                    // 递归检查并删除父目录（如果也为空）
                    var parentDir = Path.GetDirectoryName(path);
                    if (!string.IsNullOrEmpty(parentDir) &&
                        parentDir != cfg.Target &&
                        Directory.Exists(parentDir) &&
                        !Directory.EnumerateFileSystemEntries(parentDir).Any())
                    {
                        CleanEmptyDirectories(parentDir, cfg);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.WriteError($"[{cfg.Name}] 清理空目录失败: {ex.Message}");
            }
        }

        private void InitAutoSyncTimer()
        {
            autoSyncTimer = new System.Windows.Forms.Timer();
            autoSyncTimer.Tick += AutoSyncTimer_Tick;
            UpdateAutoSyncTimer();
        }

        private void UpdateAutoSyncTimer()
        {
            autoSyncTimer.Stop();
            if (Config.AutoSyncEnabled && Config.AutoSyncIntervalMinutes > 0)
            {
                autoSyncTimer.Interval = Config.AutoSyncIntervalMinutes * 60 * 1000; // 转换为毫秒
                autoSyncTimer.Start();
                Logger.WriteInfo($"定时同步已启用，间隔 {Config.AutoSyncIntervalMinutes} 分钟");
            }
            else
            {
                Logger.WriteInfo("定时同步已禁用");
            }
        }

        private void AutoSyncTimer_Tick(object sender, EventArgs e)
        {
            Logger.WriteInfo("开始定时全量同步");
            foreach (var g in Config.Groups)
            {
                Logger.WriteInfo($"[{g.Name}] 开始定时同步");
                Scanner.ScanAndLink(g);
                if (g.RemoveMissing) Scanner.RemoveDeadLinks(g);
                Logger.WriteInfo($"[{g.Name}] 定时同步完成");
            }
            Logger.WriteInfo("定时全量同步完成");
        }

    }

}
